/*
 * BufferManager.h
 *
 *  Created on: 09-Oct-2013
 *      Author: pridhvi
 */

#ifndef BUFFERMANAGER_H_
#define BUFFERMANAGER_H_
#define FRAME_NOT_FOUND -1
#include "../Global/BaseEntity.h"
//#include "../dependency/GlobalStructures.h"
#include "../Global/StructureHeaders.h"
#include "../DiskManager/DiskManager.h"
#include "../BufferManager/Frame.h"
#include "../BufferManager/ReplacementPolicy.h"
#include "../PageLayout/FreePageLinkedList.h"
#include <map>
using namespace std;

class BufferManager : virtual BaseEntity {
    static BufferManager *bmInstance_;
    int pageSize;
    map<int, int> frameLookUp; // key is page number and value is frame number
    map<int, char*> pageAddressLookUp;
    map<int, int> pageAddressInUseLookUp;

    ReplacementPolicy *LRUReplacement;
    FreePageLinkedList freePagesLL;

public:
        int bufferSize_;
    DiskManager diskMan;
    Frame **bufferPool_;
    int noOfFrames;
    //bool isDBOpen;
    int noOfDiskAccess;
    int noOfPgRead;
    int noOfTimesPgFoundInBuffer;
    int totalReqToBuffer;
    BufferManager();
    BufferManager(int sizeInMB);
    virtual ~BufferManager();

    static BufferManager* getInstance();

    /***
     * Called when user calls Buffer on with size
     */

    STATUS_CODE initializeBuffer(int sizeInMB);

    STATUS_CODE startCache(int sizeInMB);
    STATUS_CODE stopCache();
    STATUS_CODE commitCache();
    STATUS_CODE deleteBufferPool();
    STATUS_CODE displayCache();
    STATUS_CODE displayframe(int frameNo);


    /************************** DATABASE RELATED FUNCTION CALLS START************************/

    /***
     * Used to call the diskmanager createDiskFile()
     */
    STATUS_CODE createDB(string databaseName, int numOfPages);

    /***
     * Used to call the diskmanager openDiskFile()
     */
    STATUS_CODE useDB(string databaseName);

    /***
     *  Used to call the diskmanager deleteDiskFile()
     */
    STATUS_CODE dropDB(string databaseName);

    /***
     * Used for resizing the database
     */
    STATUS_CODE resizeDB(int noOfPgs); // we will double the database size -- check with avialable memory

    STATUS_CODE closeDB();
    STATUS_CODE closeDB(int cache_id);
    /************************** DATABASE RELATED FUNCTION CALLS ENDS **************************/
    // getting the requested page from heap file into ram and pinning it

    STATUS_CODE getPage(int pageNo, char*& pgData);
    STATUS_CODE getPage(int cache_id, int pageNo, char*& pgData);

    void releasePage(int pageNo, bool dirty);
    STATUS_CODE releasePage(int cache_id, int pageNo, bool dirty);
    
    
    STATUS_CODE resizeDB_cache(int cache_id); 
    STATUS_CODE flushAll(int cache_id) ;





    int getFrame(int pageNo);

    int getFreeFrame();

    void insertIntoFrameLookUp(int pageNo, int frameNo);

    STATUS_CODE flushPageToDisk(int pageNo, char* pgData);

    STATUS_CODE flushPageToDisk(int pageNo);

    STATUS_CODE flushAll();

    STATUS_CODE getPageNum(int frameNum, int& pgNo);

    STATUS_CODE getNewPage(int &pageNo, char*& pageData);
    
    STATUS_CODE freePage(int pgNo);
    
    int getFrame(int pageNo, int cache_id);

    float getHitRate();

    map<string, int> listDB();



};
#endif /* BUFFERMANAGER_H_ */
